home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari Mega Archive 1
/
Atari Mega Archive - Volume 1.iso
/
misc
/
scode.arc
/
cbw2ps.c
next >
Wrap
C/C++ Source or Header
|
1987-08-25
|
7KB
|
356 lines
/*
* Compressed ST screen (monochrome) to Postscript filter.
*
* By Moshe Braner, 861116.
*
* Postscript stuff from:
* Cwru standard bitmap image to PostScript filter,
* by J. R. Bammi.
*
* WARNING: assumes ASCII.
*
* Usage:
*
* cbw2ps [-s xsize ysize] [-t transx transy] [-r rot] [-l] [-i] file
*
* -s xsize ysize = size of postscript image - default 8.533 x 5.333"
* -1 = 1 dot per pixel - 2.133 x 1.333 inches
* -2 = 2 dots per pixel - 4.267 x 2.667
* -3 = 3 dots per pixel - 6.4 x 4
* -4 = 4 dots per pixel - 8.533 x 5.333 (default)
* -5 = 5 dots per pixel - 10.67 x 6.667
* -t transx transy = translate image - default 0.25 0.5 inches
* -r rotate = rotate image - default 0 degrees
* -l = landscape (== -r 90) - default portrait
* -i = inverse image - default no inverse
*/
#include <stdio.h>
#define OK 0
#define ERROR -1
FILE *fp, *fopen();
char scrn[32000]; /* virtual screen buffer */
char *scrnptr; /* target address for next decoded byte */
long chksum; /* chksum on input file */
int rows;
int cols;
int row;
int col;
int bferr = 0;
main(argc,argv)
int argc;
char **argv;
{
int land, inv;
char *filename;
double sizex, sizey, transx, transy, rotate;
extern double atof();
fp = stdin;
land = 0;
inv = 0;
filename = "STDIN";
sizex = 8.533333;
sizey = 5.333333;
transx = 0.25;
transy = 0.5;
rotate = 0.0;
while(--argc > 0) {
++argv;
if((*argv)[0] == '-') {
switch((*argv)[1]) {
case 'l':
case 'L':
land = 1;
break;
case 's':
case 'S':
sizex = atof(*++argv);
sizey = atof(*++argv);
argc -= 2;
break;
case 't':
case 'T':
transx = atof(*++argv);
transy = atof(*++argv);
argc -= 2;
break;
case 'r':
case 'R':
rotate = atof(*++argv);
argc--;
break;
case 'I':
case 'i':
inv = 1;
break;
case '1':
sizex = 2.133333;
sizey = 1.333333;
break;
case '2':
sizex = 4.26667;
sizey = 2.66667;
break;
case '3':
sizex = 6.4;
sizey = 4.0;
break;
case '4':
sizex = 8.533333;
sizey = 5.333333;
break;
case '5':
sizex = 10.66667;
sizey = 6.66667;
break;
default:
fprintf(stderr,
"Illegal switch \'%c\' - ignored\n",
(*argv)[1]);
}
} else {
if((fp = fopen(*argv, "r")) == (FILE *)NULL) {
fprintf(stderr,"Cannot open %s\n",*argv);
exit(1);
}
filename = *argv;
}
}
process(land,inv,filename,sizex,sizey,transx,transy,rotate);
}
process(land, inv, filename, sizex, sizey, transx, transy, rotate)
int land, inv;
char *filename;
double sizex, sizey, transx, transy, rotate;
{
int bpp, xmax, ymax, junk;
register long i;
long bytes, origsum;
register unsigned int c, s, out, mask;
register int j, bpb, shift, k;
extern unsigned int decode3();
c = fgetb() - 0x10;
chksum = ((long) c)&0x03;
if (c != 2) {
fprintf(stderr,
"%s not a monochrome image!\n",filename);
exit(1);
}
bpp = 1;
ymax = 400;
xmax = 640;
/* Scan off color table */
c = decode3();
chksum += ((long) c)&0xFFFF;
if ((c & 0x01) == 1)
inv = (! inv);
for(i = 0; i < 15; i++)
chksum += ((long) decode3())&0xFFFF;
/* decode the image itself */
rows = 400;
cols = 80;
row = 0;
col = 0;
scrnptr = scrn;
while ((c=fgetb()) != ERROR) {
if (c > 0x0F)
s = reps(c);
else
s = uniq(c);
if (s != OK)
break;
}
/* read original checksum */
origsum = (((long) decode3())&0xFFFF) << 16;
origsum += ((long) decode3())&0xFFFF;
if (bferr) {
fprintf(stderr,"Error while reading %s\n",
filename);
exit(3);
} else if (chksum != origsum) {
fprintf(stderr,"Checksum doesn't fit!\n");
exit(3);
}
fclose(fp);
/* Put out header */
printf("%%!\n/inch {72 mul} def\n");
printf("/picstr 1 string def\n");
printf("/bpp %d def\n",bpp);
printf("/scanlines %d def\n",ymax);
printf("/scansize %d def\n", xmax);
printf("/bitmapx\n{");
printf(" %d %d %d [%d 0 0 %d 0 %d]",
xmax, ymax, bpp, xmax,-ymax,ymax);
printf(" {currentfile picstr readhexstring pop} image\n} def\n");
printf("gsave\n");
printf("%f inch %f inch translate\n",transx, transy);
printf("%f rotate\n", (land == 1)? 90.0+rotate : rotate );
printf("%f inch %f inch scale\n", sizex, sizey);
printf("/clipathx\n{\tnewpath\n\t0 0 moveto\n\t%f 0 inch", sizex);
printf(" lineto\n\t%f inch %f inch lineto\n\t0 %f inch lineto\n",
sizex, sizey, sizey);
printf("\tclosepath } def\nclipathx clip\n");
printf("bitmapx\n");
/* put out bit map data */
scrnptr = scrn;
k = 0;
for (i=0; i<32000; i++) {
out = *scrnptr++;
printf ("%02x",
(unsigned int)(((inv == 1)? ~out : out)
& (unsigned int)0x00ff));
if (++k & 16) {
putchar('\n');
k = 0;
} else
putchar(' ');
}
printf("grestore\n");
printf("showpage\n");
}
/*
* Read a byte from the input file, translate it.
* Skip control chars and white space, etc.
*/
int
fgetb()
{
register int c;
again:
if (bferr)
return (ERROR);
c = getc(fp);
if (c == EOF)
bferr = 1;
if (c < ',' || c > 'z')
goto again;
if (c < 'a')
return (c - ' ');
if (c < 'm')
return (c - 'a');
if (c < 'v')
return (c - 0x55);
return (c - 0x3B);
}
/*
* Decode one (16-bit) word out of 3 bytes of the input file.
*/
unsigned int
decode3()
{
register unsigned int c;
register unsigned int dummy; /* avoid a Megamax bug */
c = (fgetb() << 12);
c |= (fgetb() << 6);
c |= fgetb();
return (c);
}
/*
* Put a decoded byte into the screen buffer.
*/
int
putbyte(b)
int b;
{
*scrnptr = (char) b;
scrnptr += cols;
if (++row >= rows) {
if (++col >= cols) {
return (ERROR);
}
scrnptr = scrn + col;
row = 0;
}
return (OK);
}
/*
* Handle a pair of decoded screen bytes.
*/
int
putword(w)
register unsigned int w;
{
register unsigned int dummy; /* avoid a Megamax bug */
chksum += ((long) w)&0xFFFF;
if (putbyte((w>>8) & 0xFF) == ERROR)
return (ERROR);
return (putbyte(w & 0xFF));
}
/*
* Decode 2 screen bytes.
*/
int
uniq(c)
register unsigned int c;
{
register unsigned int dummy; /* avoid a Megamax bug */
c <<= 12;
c |= (fgetb() << 6);
c |= fgetb();
if (bferr)
return (ERROR);
return (putword(c));
}
/*
* Decode a 4-byte repetition code.
*/
int
reps(b)
register unsigned int b;
{
register unsigned int c;
b = ((b-0x10) << 2);
c = fgetb();
b |= (c >> 4);
c <<= 12;
c |= (fgetb() << 6);
c |= fgetb();
if (bferr)
return (ERROR);
while (b--) {
if (putword(c) == ERROR)
return (ERROR);
}
return (OK);
}